import java.util.Scanner;

public class EnhancedNumberSystem {

    private static final int MAX_BITS = 32;
    private static final int DEFAULT_BITS = 8;


    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            try {
                System.out.print("\n输入数字（整数或小数，q退出）: ");
                String input = scanner.next().trim();
                if (input.equalsIgnoreCase("q")) break;

                System.out.print("字长（1-" + MAX_BITS + "，默认" + DEFAULT_BITS + "）: ");
                String bitsInput = scanner.next().trim();
                int bits = parseBits(bitsInput);

                if (isDecimal(input)) {
                    handleDecimal(input, bits);
                } else {
                    handleInteger(input, bits);
                }
            } catch (NumberFormatException e) {
                System.err.println("错误: 无效数字格式");
                scanner.nextLine();
            } catch (IllegalArgumentException e) {
                System.err.println("错误: " + e.getMessage());
            }
        }
        scanner.close();
    }

    private static void handleDecimal(String input, int bits) {
        double num = Double.parseDouble(input);
        validateDecimalRange(num);
        String[] codes = calculateDecimalCodes(num, bits);
        printResult("定点小数", codes);
    }

    private static void handleInteger(String input, int bits) {
        int num = Integer.parseInt(input);
        validateIntegerRange(num, bits);
        String[] codes = calculateIntegerCodes(num, bits);
        printResult("整数", codes);
    }

    private static int parseBits(String input) {
        if (input.isEmpty()) return DEFAULT_BITS;
        int bits = Integer.parseInt(input);
        if (bits < 1 || bits > MAX_BITS) {
            throw new IllegalArgumentException("字长范围：1-" + MAX_BITS);
        }
        return bits;
    }

    private static boolean isDecimal(String input) {
        return input.contains(".");
    }

    private static void validateDecimalRange(double num) {
        if (Math.abs(num) >= 1.0) {
            throw new IllegalArgumentException("定点小数需在(-1, 1)之间");
        }
    }

    private static void validateIntegerRange(int num, int bits) {
        int max = (1 << (bits - 1)) - 1;
        int min = -(1 << (bits - 1));
        if (num < min || num > max) {
            throw new IllegalArgumentException(bits + "位整数范围: [" + min + ", " + max + "]");
        }
    }

    private static String[] calculateDecimalCodes(double num, int bits) {
        StringBuilder process = new StringBuilder();
        String sign = num >= 0 ? "0" : "1";
        String fraction = toBinaryFraction(Math.abs(num), bits - 1);

        String trueCode = sign + fraction;
        process.append("原码: 符号位").append(sign).append("，数值位").append(fraction);

        String inverseCode = sign + (num >= 0 ? fraction : invertBits(fraction));
        process.append("\n反码: ").append(num >= 0 ? "同原码" : "数值位取反");

        String complementCode = num >= 0 ? trueCode : addBinaryOne(inverseCode);
        process.append("\n补码: ").append(num >= 0 ? "同原码" : "反码+1");

        String excessCode = toExcessCode(num, bits);
        process.append("\n移码: 偏移值转换");

        return new String[]{process.toString(), trueCode, inverseCode, complementCode, excessCode};
    }

    private static String[] calculateIntegerCodes(int num, int bits) {
        StringBuilder process = new StringBuilder();
        String sign = num >= 0 ? "0" : "1";
        String absolute = String.format("%" + (bits - 1) + "s", Integer.toBinaryString(Math.abs(num))).replace(' ', '0');
        absolute = absolute.substring(absolute.length() - (bits - 1)); // 确保长度正确

        String trueCode = sign + absolute;
        process.append("原码: 符号位").append(sign).append("，数值位").append(absolute);

        String inverseCode;
        if (num >= 0) {
            inverseCode = trueCode;
            process.append("\n反码: 同原码");
        } else {
            String inverted = invertBits(absolute);
            inverseCode = sign + inverted;
            process.append("\n反码: 数值位取反");
        }

        String complementCode;
        if (num >= 0) {
            complementCode = trueCode;
            process.append("\n补码: 同原码");
        } else {
            String inverted = invertBits(absolute);
            String complemented = addBinaryOne(inverted);
            complementCode = sign + complemented;
            process.append("\n补码: 反码+1");
        }

        int excessValue = num + (1 << (bits - 1));
        excessValue &= (1 << bits) - 1; // 确保在bits位内
        String excessCode = String.format("%" + bits + "s", Integer.toBinaryString(excessValue))
                .replace(' ', '0');
        excessCode = excessCode.substring(excessCode.length() - bits);
        process.append("\n移码: 偏移值转换（偏移量" + (1 << (bits - 1)) + "）");
        return new String[]{process.toString(), trueCode, inverseCode, complementCode, excessCode};
    }
    private static String toBinaryFraction(double num, int precision) {
        StringBuilder sb = new StringBuilder();
        double temp = num;
        for (int i = 0; i < precision; i++) {
            temp *= 2;
            sb.append(temp >= 1 ? '1' : '0');
            temp %= 1;
        }
        return sb.toString();
    }

    private static String invertBits(String binary) {
        return binary.replace('0', 'x').replace('1', '0').replace('x', '1');
    }
    private static String addBinaryOne(String binary) {
        char[] arr = binary.toCharArray();
        for (int i = arr.length - 1; i >= 0; i--) {
            if (arr[i] == '0') {
                arr[i] = '1';
                break;
            } else {
                arr[i] = '0';
            }
        }
        return new String(arr);
    }

    private static String toExcessCode(double num, int bits) {
        int offset = 1 << (bits - 1);
        int value = (int) (num * offset) + offset;
        value &= (1 << bits) - 1; // 取低bits位
        String binary = Integer.toBinaryString(value);
        return String.format("%" + bits + "s", binary)
                .replace(' ', '0').substring(0, bits);
    }

    private static void printResult(String type, String[] codes) {
        System.out.println("\n[ " + type + "计算过程 ]");
        System.out.println(codes[0]);
        System.out.println("\n[ 最终结果 ]");
        System.out.println("原码: " + codes[1]);
        System.out.println("反码: " + codes[2]);
        System.out.println("补码: " + codes[3]);
        System.out.println("移码: " + codes[4]);
    }
}